﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using Avalonia;
using Avalonia.Media;
using Avalonia.Styling;
using Bee.Base.Abstractions.Navigation;
using Bee.Base.Models.Menu;
using Bee.Base.ViewModels;
using Bee.Helpers;
using Bee.ViewModels.Menu;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Ke.Bee.Localization.Localizer.Abstractions;
using Microsoft.Extensions.Options;

namespace Bee.ViewModels;

public partial class MainWindowViewModel : ViewModelBase
{
    /// <summary>
    /// 工具按钮集合
    /// </summary>
    [ObservableProperty] private ObservableCollection<MenuItemViewModel> _toolbarMenus;

    /// <summary>
    /// 设置菜单集合
    /// </summary>
    [ObservableProperty] private ObservableCollection<MenuItemViewModel> _settingMenuItems;

    /// <summary>
    /// 侧栏耳机菜单集合
    /// </summary>
    [ObservableProperty] private IDictionary<string, ObservableCollection<MenuItemViewModel>> _sidebarMenus;
    /// <summary>
    /// 存储筛选前的二级菜单数据
    /// </summary>
    private IDictionary<string, ObservableCollection<MenuItemViewModel>> _originalSidebarMenus;

    /// <summary>
    /// 系统菜单
    /// </summary>
    private readonly List<MenuItem> _menus;

    /// <summary>
    /// 本地化对象
    /// </summary>
    private readonly ILocalizer _l;

    /// <summary>
    /// 视图导航对象
    /// </summary>
    private readonly IViewNavigate _viewNavigate;

    /// <summary>
    /// 搜索防抖
    /// </summary>
    private readonly Debounce _debounce;
    
    /// <summary>
    /// 当前页面视图模型
    /// </summary>
    [ObservableProperty] private PageViewModelBase _currentPage;

    private Func<MenuItem, MenuItemViewModel> MenuItemToViewModel => a => new MenuItemViewModel(_l[a.LocaleKey])
    {
        Key = a.Key,
        IsActive = a.IsActive == true,
        Icon = string.IsNullOrWhiteSpace(a.Icon) ? null : StreamGeometry.Parse(a.Icon),
        CommandParameter = a.CommandParameter,
        Items = a.Items.Select(MenuItemToViewModel).ToList(),
        MenuClickCommand = GetRelayCommand(a.CommandType),
        Group = _l[a.GroupLocaleKey]
    };

    /// <summary>
    /// 根据命令类型返回中继命令
    /// </summary>
    /// <param name="commandType"></param>
    /// <returns></returns>
    private IRelayCommand GetRelayCommand(string commandType)
    {
        if (!Enum.TryParse<MenuClickCommandType>(commandType, out var cmdType)) return null;
        return cmdType switch
        {
            // 激活菜单命令范围的中继命令
            MenuClickCommandType.Active => new RelayCommand<MenuItemViewModel>(menuItem =>
            {
                SetMenuActive(menuItem, () => ToolbarMenus.FirstOrDefault(a => a.IsActive));
                LoadSidebarMenus(menuItem);
            }),
            // 导航到视图的中继命令
            MenuClickCommandType.Navigate => new RelayCommand<MenuItemViewModel>(menuItem =>
            {
                SetMenuActive(menuItem, () => SidebarMenus.Values.SelectMany(a => a).FirstOrDefault(a => a.IsActive));
                if (menuItem.CommandParameter is null) return;
                // 导航到视图
                _viewNavigate.NavigateTo(menuItem.CommandParameter);
            }),
            // 主题切换返回的中继命令
            MenuClickCommandType.SwitchTheme => new RelayCommand<MenuItemViewModel>(menuItem =>
            {
                if (Application.Current is null) return;

                var tv = menuItem.CommandParameter switch
                {
                    nameof(ThemeVariant.Default) => ThemeVariant.Light,
                    nameof(ThemeVariant.Dark) => ThemeVariant.Dark,
                    _ => ThemeVariant.Default
                };

                // 可以通过 Application.Current 设置或修改 RequestedThemeVariant 的属性
                Application.Current.RequestedThemeVariant = tv;
            }),

            MenuClickCommandType.Link => new RelayCommand<MenuItemViewModel>(menuItem =>
            {
                var url = menuItem.CommandParameter;
                Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true });
            }),

            MenuClickCommandType.SwitchLanguage => new RelayCommand<MenuItemViewModel>(menuItem =>
            {
                var language = menuItem.CommandParameter;
                _l.CurrentCulture = _l.AvailableCultures.FirstOrDefault(a => a.IetfLanguageTag == language) ??
                                    Thread.CurrentThread.CurrentCulture;
                LoadToolbarMenus();
            }),

            _ => null
        };
    }

    public MainWindowViewModel(MenuConfigurationContext menuContext, ILocalizer localizer, IViewNavigate viewNavigate)
    {
        _l = localizer;
        _viewNavigate = viewNavigate;
        _viewNavigate.PropertyChanged += OnNavigatorPropertyChanged;
        _menus = menuContext.Menus;
        _debounce = new Debounce(500);
        LoadToolbarMenus();
    }

    private void OnNavigatorPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(_viewNavigate.CurrentPage))
        {
            CurrentPage = _viewNavigate.CurrentPage;
        }
    }

    /// <summary>
    /// 载入工具栏菜单
    /// </summary>
    private void LoadToolbarMenus()
    {
        var menuList = _menus.Where(a => a.Group == "Toolbar").Select(MenuItemToViewModel);
        var settingList = _menus.Where(a => a.Group == "Settings").Select(MenuItemToViewModel);

        ToolbarMenus = new ObservableCollection<MenuItemViewModel>(menuList);
        SettingMenuItems = new ObservableCollection<MenuItemViewModel>(settingList);

        LoadSidebarMenus(ToolbarMenus[0]);
    }

    /// <summary>
    /// 载入二级菜单
    /// </summary>
    /// <param name="menuItem"></param>
    private void LoadSidebarMenus(MenuItemViewModel menuItem)
    {
        // 找到激活菜单的子菜单
        var items = _menus.FirstOrDefault(a => a.Key == menuItem.Key)?.Items;
        // 将子菜单分组
        _originalSidebarMenus = SidebarMenus = ParseGroupDictionary(items!.Select(MenuItemToViewModel));
    }

    /// <summary>
    /// 设置激活菜单
    /// </summary>
    /// <param name="menuItem">要激活的项</param>
    /// <param name="callback">之前激活的项</param>
    private void SetMenuActive(MenuItemViewModel menuItem, Func<MenuItemViewModel> callback)
    {
        if (menuItem == null || menuItem.IsActive == true) return;
        // 清除之前的选中项
        var beforeItem = callback();
        if (beforeItem != null) beforeItem.IsActive = false;
        menuItem.IsActive = true;
    }

    /// <summary>
    /// 二级菜单搜索
    /// </summary>
    /// <param name="key"></param>
    public void OnSearchMenu(string key)
    {
        // 防抖是指在一定时间范围内，只有最后一次操作才会执行，如果在这段时间内再次触发操作，则重新计时
        _debounce.Trigger(() =>
        {
            var filterMenus = _originalSidebarMenus.Values
                .SelectMany(a => a)
                .Where(a => a.Text.Contains(key ?? string.Empty, StringComparison.InvariantCultureIgnoreCase));

            SidebarMenus = ParseGroupDictionary(filterMenus);
        });
    }
    
    /// <summary>
    /// 将菜单分组然后转化为字典类型
    /// </summary>
    /// <param name="menuItems"></param>
    /// <returns></returns>
    private IDictionary<string, ObservableCollection<MenuItemViewModel>> ParseGroupDictionary(IEnumerable<MenuItemViewModel> menuItems) => menuItems
        .GroupBy(a => a.Group)
        .ToDictionary(a => a.Key ?? "UNGROUPED", a => new ObservableCollection<MenuItemViewModel>(a));

    //
    // /// <summary>
    // /// 改变主题方法
    // /// </summary>
    // [RelayCommand]
    // private void ChangeTheme()
    // {
    //     if (Application.Current is null) return;
    //
    //     Application.Current.RequestedThemeVariant = Application.Current.RequestedThemeVariant == ThemeVariant.Dark
    //         ? ThemeVariant.Light
    //         : ThemeVariant.Dark;
    // }
}